
#include "stdafx.h"
#include "FreqToNote.h"

#define A		1
#define ASHARP	2
#define B		3
#define C		4
#define CSHARP	5
#define D		6
#define DSHARP	7
#define E		8
#define F		9
#define FSHARP	10
#define G		11
#define GSHARP	12

void FreqToNote::setFreq(double freq)
{
	freq_ = freq;
	this->computeNote();
}

double FreqToNote::getDifference()
{
	return diff_;
}

int FreqToNote::getNote()
{
	return note_;
}

// Computes the average of two numbers
double FreqToNote::avg(double a, double b)
{
	return (a + b) / 2;
}

// Computes note and difference from frequency.
void FreqToNote::computeNote()
{
	// Frequency must be within a reasonable range.
	if(freq_ < 30.0 || 4000.0 < freq_)
	{
		diff_ = 0.0;
		note_ = 0;
	}

	// Equivalent frequency in the 7th octive, 2000-4000 Hz.
	double equivFreq = this->freq_;
	while (equivFreq < 2000.0)
		equivFreq *= 2.0;

	// Frequency values from http://www.phy.mtu.edu/~suits/notefreqs.html.
	if (equivFreq < avg(2093.00, 2217.46))
	{
		note_ = C;
		diff_ = (equivFreq - 2093.00) * 0.152659;
		// Difference is multiplied by a scaling factor.
	}
	else if (equivFreq < avg(2217.46, 2349.32))
	{
		note_ = CSHARP;
		diff_ = (equivFreq - 2217.46) * 0.148252;
	}
	else if (equivFreq < avg(2349.32, 2489.02))
	{
		note_ = D;
		diff_ = (equivFreq - 2349.32) * 0.139932;
	}
	else if (equivFreq < avg(2489.02, 2637.02))
	{
		note_ = DSHARP;
		diff_ = (equivFreq - 2489.02) * 0.132082;
	}
	else if (equivFreq < avg(2637.02, 2793.83))
	{
		note_ = E;
		diff_ = (equivFreq - 2637.02) * 0.124668;
	}
	else if (equivFreq < avg(2793.83, 2959.96))
	{
		note_ = F;
		diff_ = (equivFreq - 2793.83) * 0.117669;
	}
	else if (equivFreq < avg(2959.96, 3135.96))
	{
		note_ = FSHARP;
		diff_ = (equivFreq - 2959.96) * 0.111069;
	}
	else if (equivFreq < avg(3135.96, 3322.44))
	{
		note_ = G;
		diff_ = (equivFreq - 3135.96) * 0.10483;
	}
	else if (equivFreq < avg(3322.44, 3520.00))
	{
		note_ = GSHARP;
		diff_ = (equivFreq - 3322.44) * 0.098948;
	}
	else if (equivFreq < avg(3520.00, 3729.31))
	{
		note_ = A;
		diff_ = (equivFreq - 3520.00) * 0.093396;
	}
	else if (equivFreq < avg(3729.31, 3951.07))
	{
		note_ = ASHARP;
		diff_ = (equivFreq - 3729.31) * 0.088153;
	}
	else // (equivFreq > avg(3729.31, 3951.07))
	{
		note_ = B;
		diff_ = (equivFreq - 3951.07) * 0.085678;
	}
}
